package naga.x.platform2.channel.meitu;

import java.util.Map;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import naga.x.platform2.app.Channel;
import naga.x.platform2.app.model.GameServer;
import naga.x.platform2.app.model.Recharge;
import naga.x.platform2.app.model.Recharge.State;
import naga.x.platform2.app.model.RechargeTemplate;
import naga.x.platform2.app.support.GameServerSupport;
import naga.x.platform2.app.support.RechargeSupport;
import naga.x.platform2.channel.meitu.support.MeiTuApi;
import naga.x.platform2.channel.meitu.support.MeiTuConfig;
import naga.x.platform2.channel.meitu.support.SDKCode;
import naga.x.platform2.channel.s399.support.S399Api;
import naga.x.platform2.support.RequestPath;
import naga.x.platform2.utils.HttpUtils;
import naga.x.platform2.utils.UUID;

/**
 * 美图游戏
 * @see <a href="http://h5.91wan.com/">美图游戏</a>
 * @author yang.li
 *
 */
@Controller
public class MeituController {
	
	@Autowired
	private MeiTuConfig config;
	@Autowired
	private MeiTuApi api;
	@Autowired
	private GameServerSupport serverSupport;
	@Autowired
	private RechargeSupport rechargeSupport;
	
	private static Channel channel = Channel.MEITU;
	
	private static final Logger LOG = LoggerFactory.getLogger(MeituController.class);

	@RequestMapping(path = RequestPath.MEITU_LOGIN, produces = "application/json; charset=UTF-8")
	@ResponseBody
	public Object login(String serverId, String userId, String userName, String sessionId) {
		Map<String, String> params = new TreeMap<String, String>();
//		protocol 100108 协议号 指定为100108 必需
		params.put("protocol", MeiTuApi.PROTOCOL_LOGIN);
//		server_auth 1 指定为1 必需
		params.put("server_auth", "1");
//		uid 1 用户id 必需
		params.put("uid", userId);
//		game_id 2 游戏id 必需
		params.put("game_id", config.getGameId());
//		server_id 0 游戏服务器id 默认为0 非必需
		params.put("server_id", serverId);
//		user_name 13800138000 用户名 必需
		params.put("user_name", userName);
//		sid hinvgc53apci0c3qv79rotivc2 用户的session_id 必需
		params.put("sid", sessionId);
//		sign a34b0e4975d58607fd1ec1f6a111f7ec 签名，签名方法见5.1签名方法 必需
		params.put("sign", api.makeSign(params));
		
		// {"uid": "xxx"}
		return HttpUtils.post(config.getApiUrl(), params);
	}
	
	@RequestMapping(path = RequestPath.MEITU_PAY, produces = "application/json; charset=UTF-8")
	@ResponseBody
	public Object pay(Integer sid, Long pid, Integer product, String uid) {
		GameServer gameServer = serverSupport.get(sid);
		if (gameServer == null) {
			return MeiTuApi.newError(S399Api.Code.SERVER_NOT_FOUND);
		}
		if (pid == null) {
			return MeiTuApi.newError(S399Api.Code.PLAYER_ID_ERROR);
		}
		RechargeTemplate template = rechargeSupport.getTemplate(product);
		if (template == null) {
			return MeiTuApi.newError(S399Api.Code.RECHARGE_PRODUCT_NOT_FOUND);
		}
		Map<String, String> params = new TreeMap<String, String>();
//		protocol 100601 协议号 指定为 100601 必需
		params.put("protocol", MeiTuApi.PROTOCOL_PAY);
//		subject 游戏元宝2个 商品名称 必需
		params.put("subject", template.getName());
//		total_fee 2.00 总共花费，单位为元 必需
		params.put("total_fee", String.valueOf(template.getPrice()));
//		uid 1 用户uid 必需
		params.put("uid", uid);
//		game_id 68 由平台分配的游戏id 必需
		params.put("game_id", config.getGameId());
//		server_id 0 游戏服务器id 必需
		params.put("server_id", String.valueOf(sid));
//		role_id 3 游戏中角色ID 非必需
		params.put("role_id", String.valueOf(pid));
//		role_name 小明 角色名 非必需
//		role_grade 60 角色等级 非必需
//		trade_no 12345678 cp内部的订单号 非必须
		params.put("trade_no", UUID.randomUUID().toString());
//		notify_url http://h5.91wan.com/notify_url.php 异步通知地址（请勿带任何参数） 必需
		params.put("notify_url", config.getPayCallbackUrl());
//		callback_url http://h5.91wan.com/callbcak_url.php 支付完成后跳转回的游戏地址（游戏原地址） 必需
		params.put("callback_url", config.getClientUrl());
//		sign a34b0e4975d58607fd1ec1f6a111f7ec 签名（参考4.1签名方法） 必需
		params.put("sign", api.makeSign(params));
		
		JSONObject res = JSON.parseObject(HttpUtils.post(config.getApiUrl(), params));
		if (res == null) {
			return MeiTuApi.newError(S399Api.Code.TIMEOUT);
		}
//		status 200 状态代码
//		token 8d4766db38009a97b114a59ef991cca840352322 订单token
//		out_trade_no H52015062417461816802 订单号
		int status = res.getIntValue("status");
		if (status != SDKCode.SUCC.code) {
			String msg = res.getString("msg");
			return MeiTuApi.newError(S399Api.Code.SYSTEM_ERROR.code, msg != null ? msg : S399Api.Code.SYSTEM_ERROR.msg);
		}

		String token = res.getString("token");
		String out_trade_no = res.getString("out_trade_no"); // 美图订单号
		String trade_no = params.get("trade_no"); // 我方订单号
		Recharge order = new Recharge(channel.withPrefix(out_trade_no), pid, gameServer.getId(), template.getPrice(), template.getStone(), template.getId(), channel.name);
		order.setAttach(trade_no);
		if (!rechargeSupport.offer(order, State.INIT)) {
			LOG.info("[MEITU ORDER ERR]ID[{}]SERVER[{}]PID[{}]PRODUCT[{}]UID[{}]CAUSE[DUP]", out_trade_no, sid, product, uid);
			return MeiTuApi.newError(S399Api.Code.ORDER_DUPLICATED);
		}
		return api.newOrder(token);
	}
	
	@RequestMapping(path = RequestPath.MEITU_PAY_CALLBACK, produces = "application/json; charset=UTF-8")
	@ResponseBody
	public Object payCallback(String out_trade_no, String trade_no, String total_fee, String notify_time, String sign) {
		Map<String, String> params = new TreeMap<String, String>();
//		out_trade_no H52015062417461816802 订单号 非空
		params.put("out_trade_no", out_trade_no);
//		trade_no 12345678 cp内部的订单号 可空
		params.put("trade_no", trade_no);
//		total_fee 6.66 支付价格 非空
		params.put("total_fee", total_fee);
//		notify_time 1435830761 异步通知时间 非空
		params.put("notify_time", notify_time);
//		sign a34b0e4975d58607fd1ec1f6a111f7ec 签名，签名方法见4.1签名方法 非空
		String s = api.makeSign(params);
		if (!s.equals(sign)) {
			LOG.info("[MEITU PAY ERR]OUTTRADENO[{}]TRADENO[{}]TOTALFEE[{}]TIME[{}]SIGN[{}]SIGN2[{}]CAUSE[SIGNERR]",
					out_trade_no, trade_no, total_fee, notify_time, sign, s);
			return "signerr";
		}
		String orderId = channel.withPrefix(out_trade_no);
		Recharge recharge = rechargeSupport.find(orderId);
		if (recharge == null) {
			LOG.info("[MEITU PAY ERR]OUTTRADENO[{}]TRADENO[{}]TOTALFEE[{}]TIME[{}]SIGN[{}]CAUSE[ORDERERR]",
					out_trade_no, trade_no, total_fee, notify_time, sign);
			return "ordererr";
		}
		if (recharge.getState() != State.INIT) {
			LOG.info("[MEITU PAY ERR]OUTTRADENO[{}]TRADENO[{}]TOTALFEE[{}]TIME[{}]SIGN[{}]CAUSE[DUP]",
					out_trade_no, trade_no, total_fee, notify_time, sign);
			return "success";
		}
		// 更新订单状态，并通知游戏服
		boolean succ = rechargeSupport.offer(recharge, State.SUCC);
		LOG.info("[MEITU PAY SUCC]OUTTRADENO[{}]TRADENO[{}]TOTALFEE[{}]TIME[{}]SIGN[{}]SUCC[{}]",
				out_trade_no, trade_no, total_fee, notify_time, sign, succ ? 1 : 0);
		return "success";
	}
	
	
	
}
